home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 2
/
United Public Domain Gold 2.iso
/
utilities
/
pu022.dms
/
pu022.adf
/
Source
/
Source.LZH
/
chemest.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-12
|
27KB
|
1,126 lines
/***************************************************************************
chemest.c : Hauptprogramm von Chemesthetics
***************************************************************************/
#include <stdio.h>
#include <math.h>
#include <libraries/mathffp.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <libraries/dosextens.h>
#include <libraries/arpbase.h>
#include <libraries/reqbase.h>
#include <clib/req_protos.h>
#include <req.h> /* enthält #pragmas für req.library */
#include <exec/memory.h>
#include <time.h>
#include <proto/mathffp.h>
#include "messages.h"
#include "chem_defs.h"
#include "chemest.h"
#define OK 0
#define NOK 1
#define RESX 640.0 /* Breite des Bildes */
double VERGRFAKTOR = 0.3; /* Umrechnungsfaktor pm -> Pixels */
int HEIGHT = 256; /* Default, wird bei NTSC-Screen geaendert */
BOOL reflexion = FALSE, reqlib_used=FALSE;
int koordmx, koordmy, n, ref;
int reflexionsfarbe, schattenfarbe, aktfarb, beanz; /*Anzahl der Kalotten, die
das betrachtete Atom
berhren bzw. schneiden*/
double mattheit, matthm1, abstand, aspect, vergr, zf;
int drehx = 0, drehy = 0, drehz = 0;
VEKTOR l, b; /*Lichtquelle, Beobachter*/
int atomanz; /*Anzahl der Atome */
int geladene_Atome; /* Anzahl der Atome im Datenfile */
T_A a, alt; /*Atome */
T_MB mb; /*moegliche Beruehrungen*/
long conwin;
char dn[DSIZE+FCHARS+2];
char Dateiname[FCHARS+1], IFFDateiname[FCHARS+1];
char Pfadname[DSIZE+1],Titel[80];
UBYTE *atomliste[105];
USHORT code;
USHORT GadgetID;
struct Atom *GAtom[106];
struct ChemPrefs ChemPrefs= { 1.5,TRUE,TRUE,FALSE };
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct ArpBase *ArpBase;
struct ReqLib *ReqBase;
struct Screen *FirstScreen;
struct Window *Window1, *Window2;
struct IntuiMessage *message;
struct Gadget *GadgetPtr;
struct Remember *RememberPtr = NULL;
struct Process *MyProcess;
struct ReqFileRequester FileStr; /* kommt aus reqbase.h */
FILE *datei;
APTR OldErrorWin; /* Windowstruktur vor dem Starten des Tasks */
extern char ProgId[], Version[];
/* Prototypes for functions defined in chemest.c */
#ifndef __NOPROTO
#ifndef __PROTO
#define __PROTO(a) a
#endif
#else
#ifndef __PROTO
#define __PROTO(a) ()
#endif
#endif
int dateieinlesen __PROTO((void));
void dateispeichern __PROTO((void));
void Bild_speichern __PROTO((void));
void Load_Datafile __PROTO((void));
void Farben __PROTO((void));
void set_screenmode __PROTO((int height));
void bringeaufeinheitsvektor __PROTO((register VEKTOR *v));
double cowinkelzwischen __PROTO((VEKTOR *v_v1, VEKTOR *v_v2));
void plot __PROTO((double x, double y, double hell1, double hell2));
void spiegle __PROTO((VEKTOR *v_v2, VEKTOR *v1));
void moeglicheberuehrungentesten __PROTO((void));
BOOL beruehrung __PROTO((double x, double y, double z));
int __regargs atomzeichnen __PROTO((ATOMTYP *v_m));
void atomskizze __PROTO((ATOMTYP *v_m));
void atomeordnen __PROTO((void));
void atomezentrieren __PROTO((void));
void atomedrehen __PROTO((char achse, double dx));
int farbnr __PROTO((ATOMTYP *v_atom));
void PrintName __PROTO((void));
void Werte_loeschen __PROTO((void));
void Menu_Auswertung __PROTO((USHORT Menu_Nr));
void main __PROTO((void));
int Nachricht __PROTO((struct Window *win));
void Open_All __PROTO((void));
void Close_All __PROTO((BOOL status));
/* ------------------------------- external references ------------------ */
extern void Prepare(),PrepareLogo(),FreeLogo(),PrepareEGadgets(),
FreeEGadgets(),floh(),StatRequest(),license(),SimpleRequest(),
SysInfo();
extern long save();
extern short TwoGadRequest();
extern UBYTE *AllocRemeber();
extern double bildverh();
extern struct Message *GetMsg();
extern struct Task *FindTask();
extern struct Window *OpenWindow();
/* --------- Menuefunktionen ----------------------------------------*/
int dateieinlesen()
/* versucht, die Molekuel-Datei dn einzulesen */
{
char dummy[20];
int i;
FILE *datei;
strcpy(Titel,LOAD_MOL);
if(FileRequester(&FileStr))
{
datei = fopen(dn, "r");
if (datei)
{
SetPointer(Window1, wptr->Pointer, wptr->Height,
wptr->Width, wptr->XOffset, wptr->YOffset);
Werte_loeschen(); /* alte Werte loeschen */
fgets(dummy,4,datei);
atomanz=atoi(dummy);
if(atomanz==0)
{
SimpleRequest(WRONG_DATA);
return 0;
}
for (i = 1; i <= atomanz; i++)
{
fgets(a[i].name, 4, datei);
a[i].name[strlen(a[i].name)-1]='\0'; /* \n loeschen */
fgets(dummy,7,datei); a[i].x=atoi(dummy);
fgets(dummy,7,datei); a[i].y=atoi(dummy);
fgets(dummy,7,datei); a[i].z=atoi(dummy);
fgets(dummy,7,datei); a[i].r=atoi(dummy);
alt[i] = a[i]; /* Originale f. Editieren sichern */
}
fgets(dummy,19,datei); zf=atof(dummy);
fgets(dummy,19,datei); drehx=atoi(dummy);
fgets(dummy,19,datei); drehy=atoi(dummy);
fgets(dummy,19,datei); drehz=atoi(dummy);
fgets(dummy,19,datei); l.x=atof(dummy);
fgets(dummy,19,datei); l.y=atof(dummy);
fgets(dummy,19,datei); l.z=atof(dummy);
fgets(dummy,19,datei); ref=atoi(dummy);
fclose(datei);
ClearPointer(Window1);
if (zf == 0.0 || zf > 100)
{
SimpleRequest(WRONG_DATA);
return 0;
}
else
return 1;
}
else
return 0;
}
else
return 0;
reqlib_used=TRUE; /* wirklich benutzt! */
}
void dateispeichern() /* speichert die Molekuel-Datei */
{
int i;
strcpy(Titel,SAVE_MOL);
if(FileRequester(&FileStr))
{
datei = fopen(dn, "w");
if (datei)
{
SetPointer(Window1, wptr->Pointer, wptr->Height,
wptr->Width, wptr->XOffset, wptr->YOffset);
fprintf(datei, "%d\n", atomanz);
for (i = 1; i <= atomanz; i++)
{
fprintf(datei, "%s\n", alt[i].name);
fprintf(datei, "%d\n", alt[i].x);
fprintf(datei, "%d\n", alt[i].y);
fprintf(datei, "%d\n", alt[i].z);
fprintf(datei, "%d\n", alt[i].r);
}
fprintf(datei, "%lf\n", zf);
fprintf(datei, "%d\n", drehx);
fprintf(datei, "%d\n", drehy);
fprintf(datei, "%d\n", drehz);
fprintf(datei, "%lf\n", l.x);
fprintf(datei, "%lf\n", l.y);
fprintf(datei, "%lf\n", l.z);
fprintf(datei, "%d\n", ref);
fclose(datei);
ClearPointer(Window1);
}
}
reqlib_used=TRUE; /* wirklich benutzt! */
}
void Bild_speichern()
{
int i;
i = strpos(Dateiname, ".cdm");
if (i > 0)
{
strncpy(IFFDateiname, Dateiname, i);
IFFDateiname[i] = '\0';
strcat(IFFDateiname, ".iff");
}
strcpy(Titel,SAVE_IFF);
strcpy(Dateiname,IFFDateiname);
if(FileRequester(&FileStr))
{
SetPointer(Window1, wptr->Pointer, wptr->Height,
wptr->Width, wptr->XOffset, wptr->YOffset);
if(!(save(dn,FirstScreen,Window1->Width,HEIGHT)))
{
ClearPointer(Window1);
SimpleRequest("%s", IFF_ERROR);
}
ClearPointer(Window1);
}
reqlib_used=TRUE;
}
void Load_Datafile()
{
int i;
char dummy[20];
#ifdef GERMAN
datei = fopen("chems_g.dat", "r");
#endif
#ifdef ENGLISH
datei = fopen("chems_e.dat", "r");
#endif
if (datei)
{
SetPointer(Window1, wptr->Pointer, wptr->Height,
wptr->Width, wptr->XOffset, wptr->YOffset);
WrConWin(conwin, READING_DATA);
fgets(dummy,19,datei); geladene_Atome=atoi(dummy);
for (i = 1; i <= geladene_Atome; i++)
{
GAtom[i] = (struct Atom *) AllocRemember(&RememberPtr,
sizeof(struct Atom), MEMF_CLEAR);
if (GAtom[i] == NULL)
{
WrConWin(conwin, ERROR_NO_MEM);
DisplayAlert(RECOVERY_ALERT,
#ifdef GERMAN
"\1\0\30 Kein Speicher fuer Daten-File\0c\1\0\50 Maustaste druecken.\0\0",
#endif
#ifdef ENGLISH
"\1\0\30 No memory for data file\0c\1\0\50 Click mouse button.\0\0",
#endif
70);
Close_All(NOK);
}
fgets(GAtom[i]->Kurzz, 4, datei);
GAtom[i]->Kurzz[strlen(GAtom[i]->Kurzz) - 1] = '\0';
fgets(GAtom[i]->Name, 21, datei);
atomliste[i - 1] = (UBYTE *) GAtom[i]->Name;
GAtom[i]->Name[strlen(GAtom[i]->Name) - 1] = '\0';
fgets(dummy,19,datei); GAtom[i]->Farbe=atoi(dummy);
}
GAtom[105] = (struct Atom *) AllocRemember(&RememberPtr,
sizeof(struct Atom), MEMF_CLEAR);
strcpy(GAtom[105]->Name, "??????????");
fclose(datei);
WrConWin(conwin, "ok\n");
ClearPointer(Window1);
}
else
{
WrConWin(conwin, ERROR_OPEN_DATA);
Delay(150L);
Close_All(NOK);
}
}
void Farben()
{
int rwert;
rwert = palette_request(Window1, -1, -1, PALETTE_REQ, "DEFAULT", 4);
if (rwert == 5) /* Default Farben! */
LoadRGB4(&FirstScreen->ViewPort, &Def_Pal[0], 16);
}
void set_screenmode(height) /* undokumentiert!!, ändert Screen in NTSC-
oder PAL-Screen, je nach 'height' */
int height;
{
MyProcess->pr_WindowPtr=OldErrorWin;
if (Window1)
ClearMenuStrip(Window1);
if (Window1)
CloseWindowSafely(Window1, NULL);
if (FirstScreen)
CloseScreen(FirstScreen);
HEIGHT=height;
if((HEIGHT > 200) && (GfxBase->DisplayFlags & (UWORD)NTSC))
HEIGHT=200;
FirstNewScreen.Height = HEIGHT;
if (!(FirstScreen = (struct Screen *)
OpenScreen(&FirstNewScreen)))
{
WrConWin(conwin, NO_SCREEN);
Delay(150L);
Close_All(NOK);
}
LoadRGB4(&FirstScreen->ViewPort, &Pal[0], 16);
HauptFenster.Height = HEIGHT;
HauptFenster.Screen = FirstScreen;
if (!(Window1 = (struct Window *)
OpenWindow(&HauptFenster)))
{
WrConWin(conwin, NO_MAIN_WIN);
Delay(150L);
Close_All(NOK);
}
SetMenuStrip(Window1, &Menu1);
MyProcess = (struct Process *)FindTask((char *)0);
OldErrorWin = MyProcess->pr_WindowPtr; /* alten Window-Pointer sichern */
MyProcess->pr_WindowPtr=(APTR) Window1; /* Requests auf neuen Screen */
koordmy = round(((double) HEIGHT - 26.0) / 2.0);
if(HEIGHT<256)
ChemPrefs.bv=2.0;
else
ChemPrefs.bv=1.5;
aspect = ((double) HEIGHT - 26.0) / RESX * ChemPrefs.bv;
ShowTitle(FirstScreen,ChemPrefs.Title);
}
/* --------- interne Programmroutinen -------------------------------*/
void bringeaufeinheitsvektor(v)
register VEKTOR *v;
/* Der Vektor wird durch seine Laenge dividiert
und erhaelt dadurch die Laenge 1 */
{
register double r; /*Laenge*/
r = sqrt(v->x * v->x + v->y * v->y + v->z * v->z);
if (r > 0.0)
{
v->x = v->x / r;
v->y = v->y / r;
v->z = v->z / r;
}
}
double cowinkelzwischen(v_v1, v_v2)
VEKTOR *v_v1, *v_v2;
/* Cosinus des Winkels zwischen den Vektoren v1 und v2 */
{
double r_cowinkelzwischen;
VEKTOR v1, v2;
v1 = *v_v1;
v2 = *v_v2;
bringeaufeinheitsvektor(&v1);
bringeaufeinheitsvektor(&v2);
r_cowinkelzwischen = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
return r_cowinkelzwischen;
}
void plot(x, y, hell1, hell2)
double x, y, hell1, hell2;
/* Farbgebung nach Ordered-Dither-Verfahren
in 17 Helligkeisstufen
Uebergabe: 0 <= hell <= 16
hell1: Farbe der Kalotte
hell2: Spiegelung der Beleuchtung */
{
typedef char T_FARBMATRIX[4][4];
static T_FARBMATRIX farbmatrix =
{
{0, 8, 2, 10},
{12, 4, 14, 6},
{3, 11, 1, 9},
{15, 7, 13, 5}};
int kx, ky;
kx = round(koordmx + x);
ky = round(koordmy - y);
if (hell2 > (double) farbmatrix[(kx & 3)][(ky & 3)])
Pixel(Window1, reflexionsfarbe, kx, ky) /* Spiegelung */
;
else if (hell1 > (double) farbmatrix[(kx & 3)][(ky & 3)])
Pixel(Window1, aktfarb, kx, ky) /* Farbe der Kalotte */
;
else
Pixel(Window1, schattenfarbe, kx, ky); /* Schatten */
}
void spiegle(v_v2, v1)
VEKTOR *v_v2, *v1;
/* v1 wird an der Ebene gespiegelt, die zu v2 normal steht */
{
VEKTOR v2;
double coa; /* 1/Cos des eingeschlossenen Winkels */
v2 = *v_v2;
bringeaufeinheitsvektor(v1);
bringeaufeinheitsvektor(&v2);
coa = -1.0 / (v1->x * v2.x + v1->y * v2.y + v1->z * v2.z);
v1->x = v1->x * coa + 2.0 * v2.x;
v1->y = v1->y * coa + 2.0 * v2.y;
v1->z = v1->z * coa + 2.0 * v2.z;
}
void moeglicheberuehrungentesten()
/* laedt die Nummern aller Atome, die das betrachtete Atom
schneiden oder berhren, ins Array mb */
{
int i;
double dist; /* Abstand zwischen den Mittelpunkten des
betrachteten und eines anderen Atomes */
beanz = 0;
if (n > 1)
{
for (i = 1; i <= n - 1; i++)
{
dist = (double) ((int) (a[n].x - a[i].x) * (int) (a[n].x - a[i].x))
+ (double) ((int) (a[n].y - a[i].y) * (int) (a[n].y - a[i].y))
+ (double) ((int) (a[n].z - a[i].z) * (int) (a[n].z - a[i].z));
if (dist < 1e-5)
dist = 1e-5;
if (sqrt(dist) < (double) ((double) a[i].r + a[n].r))
{
beanz++;
mb[beanz] = i;
}
}
}
}
BOOL beruehrung(x, y, z)
double x, y, z;
/* testet, ob der Punkt (x,y,z), der auf der Oberflaeche
der betrachteten Kalotte liegt, eventuell innerhalb einer
anderen Kalotte liegt und deshalb unsichtbar bleiben muss:
=> Beruehrung := true */
{
BOOL r_beruehrung;
int i;
double dist; /*Abstand der Mittelpunkte*/
BOOL flag; /*wird gesetzt, wenn die
oben genannte Bedingung zutrifft */
r_beruehrung = FALSE;
if (beanz > 0)
{
i = 1;
flag = FALSE;
do
{
dist = (x - a[mb[i]].x) * (x - a[mb[i]].x)
+ (y - a[mb[i]].y) * (y - a[mb[i]].y)
+ (z - a[mb[i]].z) * (z - a[mb[i]].z);
if (dist < 1e-5)
dist = 1e-5;
if (sqrt(dist) < (double) a[mb[i]].r)
flag = TRUE;
i++;
} while (!((i > beanz) || flag));
if (flag)
r_beruehrung = TRUE;
}
return r_beruehrung;
}
int __regargs atomzeichnen(v_m)
ATOMTYP *v_m;
/* zeichnet eine Kalotte */
{
ATOMTYP m;
int xbild, zbild, zmbild, rbild, rzbild, mxbild, mzbild, lirand,
rerand; /* Anfang, Ende einer Pixelzeile */
double farbe1, farbe2, perspfaktor, vp, avp, r2double, rz2double,
radbild, r2bild, cowinkel; /* Cosinus */
VEKTOR o, vo, vl, vb, vs; /* vgl. Skizze! */
m = *v_m;
moeglicheberuehrungentesten();
perspfaktor = abstand / (abstand + m.y);
vp = vergr * perspfaktor;
avp = aspect / vp;
r2double = (double) ((int) (m.r) * (int) (m.r));
radbild = m.r * vp;
mxbild = round(m.x / avp); /*Koordinaten des Mittelpunktes*/
mzbild = round(m.z * vp); /*der Kalotte in Pixels */
rbild = trunc(radbild);
r2bild = radbild * radbild;
for (zbild = rbild; zbild >= -rbild; zbild--)
{
vo.z = zbild / vp;
o.z = vo.z + m.z;
vl.z = l.z - o.z;
rz2double = r2double - vo.z * vo.z;
rzbild = trunc(sqrt(r2bild - (double) (zbild * zbild)) / aspect);
lirand = 20000;
rerand = 20000;
xbild = -rzbild; /* Feststellen der Raender des
sichtbaren Bereiches einer
Pixelzeile der Kalotte */
do
{
vo.x = xbild * avp;
vo.y = -sqrt(rz2double - vo.x * vo.x);
if (beruehrung(m.x + vo.x, m.y + vo.y, o.z))
(xbild)++;
else
lirand = xbild;
} while (!((lirand == xbild) || (xbild > rzbild)));
if (lirand <= rzbild)
{
xbild = rzbild;
do
{
vo.x = xbild * avp;
vo.y = -sqrt(rz2double - vo.x * vo.x);
if (beruehrung(m.x + vo.x, m.y + vo.y, o.z))
(xbild)--;
else
rerand = xbild;
} while (!((rerand == xbild) || (xbild < -rzbild)));
zmbild = zbild + mzbild; /* Berechnung der Farbe aller sichtbaren Punkte
der Pixelzeile */
for (xbild = lirand; xbild <= rerand; xbild++)
{
farbe2 = 0.0;
vo.x = xbild * avp;
vo.y = -sqrt(rz2double - vo.x * vo.x);
o.x = vo.x + m.x;
o.y = vo.y + m.y;
vl.x = l.x - o.x;
vl.y = l.y - o.y;
cowinkel = cowinkelzwischen(&vl, &vo);
farbe1 = 16.0 * cowinkel; /* Reflexion */
if (reflexion)
if (cowinkel > 0.0)
{
vs = vl;
spiegle(&vo, &vs); /*vS enthlt jetzt den gespiegelten Lichtvektor*/
vb.x = b.x - o.x;
vb.y = b.y - o.y;
vb.z = b.z - o.z;
cowinkel = cowinkelzwischen(&vb, &vs);
cowinkel = cowinkel / mattheit - matthm1;
farbe2 = 16.0 * cowinkel;
}
plot((double) xbild + mxbild, (double) zmbild, farbe1, farbe2);
if (message = (struct IntuiMessage *) GetMsg(Window1->UserPort))
{
int nklasse;
nklasse = message->Class;
code = message->Code;
GadgetPtr = (struct Gadget *) message->IAddress;
GadgetID = GadgetPtr->GadgetID;
ReplyMsg(message);
while (message = (struct IntuiMessage *) GetMsg(Window1->UserPort))
ReplyMsg(message);
return nklasse;
}
}
}
}
return 0;
}
void atomskizze(v_m)
ATOMTYP *v_m;
/* zeichnet den Umriss einer Kalotte */
{
ATOMTYP m;
double vp, radbild; /*Radius der Kalotte am Bild in Pixels */
m = *v_m;
vp = vergr * abstand / (abstand + m.y);
radbild = vp * (double) m.r;
Ellipse(Window1, aktfarb, koordmx + round(vp * m.x / aspect), koordmy - round(vp * m.z),
(int) (round(radbild / aspect) - 2.0), (int) (round(radbild) - 2.0));
}
void atomeordnen()
/* ordnet die Atome von hinten nach vorne */
{
int i;
ATOMTYP zwi;
BOOL flag;
do
{
flag = FALSE;
for (i = 1; i <= atomanz - 1; i++)
{
if ((a[i].y < a[i + 1].y))
{
zwi = a[i];
a[i] = a[i + 1];
a[i + 1] = zwi;
flag = TRUE;
}
}
} while (flag != FALSE);
}
void atomezentrieren()
/* zentriert die Atome im Koordinatensystem */
{
int i, dx, dy, dz, minx, maxx, miny, maxy, minz, maxz;
maxx = -30000;
maxy = maxx;
maxz = maxx;
minx = 30000;
miny = minx;
minz = minx;
for (i = 1; i <= atomanz; i++)
{
if (a[i].x < minx)
minx = a[i].x;
if (a[i].x > maxx)
maxx = a[i].x;
if (a[i].y < miny)
miny = a[i].y;
if (a[i].y > maxy)
maxy = a[i].y;
if (a[i].z < minz)
minz = a[i].z;
if (a[i].z > maxz)
maxz = a[i].z;
}
dx = (int) round(((double) maxx + minx) / 2.0);
dy = (int) round(((double) maxy + miny) / 2.0);
dz = (int) round(((double) maxz + minz) / 2.0);
for (i = 1; i <= atomanz; i++)
{
a[i].x = a[i].x - dx;
a[i].y = a[i].y - dy;
a[i].z = a[i].z - dz;
}
}
void atomedrehen(achse, dx)
char achse;
double dx;
/* dreht alle Atome um den Winkel dx
um die Koordinatenachse "Achse" */
{
int xalt, yalt, zalt, i;
double sx, cx;
dx = dx / 180.0 * PI; /*Umrechnung in rad*/
sx = sin(dx);
cx = cos(dx);
for (i = 1; i <= atomanz; i++)
{
xalt = a[i].x;
yalt = a[i].y;
zalt = a[i].z;
switch (achse)
{
case 'x':
a[i].y = round(yalt * cx + zalt * sx);
a[i].z = round(-yalt * sx + zalt * cx);
break;
case 'y':
a[i].x = round(xalt * cx - zalt * sx);
a[i].z = round(xalt * sx + zalt * cx);
break;
case 'z':
a[i].x = round(xalt * cx + yalt * sx);
a[i].y = round(-xalt * sx + yalt * cx);
break;
}
}
}
int farbnr(v_atom)
ATOMTYP *v_atom;
/* Zuteilung der Farbe einer Kalotte */
{
register int i;
int f;
ATOMTYP atom;
f = 0;
atom = *v_atom;
/* in diese Tabelle gewuenschte Farben je nach Graphikkarte
und persoenlichem Geschmack eintragen (nicht Schwarz!)
und Tabelle nach Bedarf erweitern */
reflexionsfarbe = 2;
schattenfarbe = 1;
for (i = 1; i <= geladene_Atome; i++)
{
if (!strcmp(atom.name, GAtom[i]->Kurzz))
{
f = GAtom[i]->Farbe;
i = geladene_Atome;
}
}
if (f == 0)
{
SimpleRequest("%s %s", NO_ATOM, atom.name);
return (7); /* als default nehmen */
}
else
return (f);
}
void PrintName()
{
int i;
char dummy[31];
i = strpos(Dateiname, ".");
if (i > 0)
{
strncpy(dummy, Dateiname, i);
dummy[i] = '\0';
}
else
strcpy(dummy, Dateiname);
Shadow(Window1, dummy, 1, 13, 20, HEIGHT - 6);
}
void Werte_loeschen()
{
register int i;
for (i = 1; i <= MAXATOM; i++)
{
strcpy(alt[i].name, "");
alt[i].x = 0;
alt[i].y = 0;
alt[i].z = 0;
alt[i].r = 0;
strcpy(a[i].name, "");
a[i].x = 0;
a[i].y = 0;
a[i].z = 0;
a[i].r = 0;
}
zf = 0.0;
drehx = 0;
drehy = 0;
drehz = 0;
l.x = 0.0;
l.y = 0.0;
l.z = 0.0;
ref = 0;
}
void Menu_Auswertung(Menu_Nr)
USHORT Menu_Nr;
{
USHORT Menu, MenuItem;
long stime,etime;
Menu = MENUNUM(Menu_Nr);
MenuItem = ITEMNUM(Menu_Nr);
/* SubItem = SUBNUM(Menu_Nr); */ /* fuer spaeteren Gebrauch */
switch (Menu)
{
case 0: /* Copyright, Credits */
switch (MenuItem)
{
case 3:
Credits();
break;
}
break;
case 1: /* Projekt */
switch (MenuItem)
{
case 0:
if (dateieinlesen())
Prepare();
break;
case 1:
dateispeichern();
break;
case 2:
Bild_speichern();
break;
case 3:
SysInfo();
break;
case 4:
if(TwoGadRequest(CONFIRM_QUIT))
Close_All(OK);
break;
}
break;
case 2: /* Edit */
switch (MenuItem)
{
case 0:
if (Eingabe())
Prepare(); /* bei OK */
break;
case 1:
Farben();
break;
}
break;
case 3: /* Zeichnen */
switch (MenuItem)
{
case 0:
Cls(Window1, 0);
Logo();
for (n = 1; n <= atomanz; n++)
{
aktfarb = farbnr(&a[n]);
atomskizze(&a[n]);
}
PrintName();
break;
case 1:
Block(Window1, 0, 20, HEIGHT - 12, 280, 11);
Print(Window1, PRESS_MB, 1, 0, 20, HEIGHT - 6);
Logo();
stime=time(&stime);
for (n = 1; n <= atomanz; n++)
{
aktfarb = farbnr(&a[n]);
if (atomzeichnen(&a[n])) /* solange FALSE, bis Maustaste gedr. */
break;
}
etime=time(&etime);
Block(Window1, 0, 20, HEIGHT - 12, 280, 11);
PrintName();
StatRequest(Window1,etime-stime,n-1);
break;
}
break;
case 4: /* Einstellungen */
switch (MenuItem)
{
case 0:
prefs(&ChemPrefs);
if(ChemPrefs.bv<1.0)
ChemPrefs.bv=1.0;
aspect = ((double) HEIGHT - 26.0) / RESX * ChemPrefs.bv;
break;
}
break;
}
}
void main() /* Hauptprogramm */
{
Open_All();
koordmx = round(RESX / 2.0);
koordmy = round(((double) HEIGHT - 26.0) / 2.0);
if(HEIGHT<256)
ChemPrefs.bv=2.0;
aspect = ((double) HEIGHT - 26.0) / RESX * ChemPrefs.bv;
vergr = VERGRFAKTOR;
Werte_loeschen(); /* sicherheitshalber loeschen, damit nicht irgend-
welcher Muell vorhanden ist */
FOREVER
{
switch (Nachricht(Window1))
{
case MENUPICK:
Menu_Auswertung(code);
break;
case VANILLAKEY: /* alle diese Features sind nicht dokumentiert,
da sie nur für mich interessant sind! */
switch(code)
{
case 'l':
case 'L':
license();
break;
case 'N':
set_screenmode(200);
break;
case 'P':
set_screenmode(256);
break;
}
break;
}
}
}
/*--------------------------- Unterroutinen ------------------------------*/
int Nachricht(win)
struct Window *win;
{
int nklasse;
FOREVER
{
if ((message = (struct IntuiMessage *) GetMsg(win->UserPort)) == NULL)
{
Wait(1L << win->UserPort->mp_SigBit);
continue;
}
nklasse = message->Class;
code = message->Code;
GadgetPtr = (struct Gadget *) message->IAddress;
GadgetID = GadgetPtr->GadgetID;
ReplyMsg(message);
while (message = (struct IntuiMessage *) GetMsg(win->UserPort))
ReplyMsg(message);
break;
}
return (nklasse);
}
void Open_All()
{
if (!(IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library", 0L)))
{
printf(NO_INTUI);
Close_All(NOK);
}
conwin = OpenRevWin("CON:120/88/400/80/Chemesthetics");
if (conwin == -1)
{
printf(NO_CONSOLE);
Close_All(NOK);
}
if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L)))
{
WrConWin(conwin, NO_GFX);
Delay(150L);
Close_All(NOK);
}
if (!(TestFile("libs:arp.library")))
{
WrConWin(conwin, NO_ARP);
Delay(150L);
Close_All(NOK);
}
if (!(ArpBase = (struct ArpBase *) OpenLibrary(ArpName, ArpVersion)))
{
WrConWin(conwin, ERROR_NO_ARP);
Delay(150L);
Close_All(NOK);
}
if (!(TestFile("libs:req.library")))
{
WrConWin(conwin, NO_REQ_LIB);
Delay(150L);
Close_All(NOK);
}
else
{
if (!(ReqBase = (struct ReqLib *) OpenLibrary("req.library",0L)))
{
WrConWin(conwin, ERROR_NO_REQ);
Delay(150L);
Close_All(NOK);
}
else
{
dn[0]=0;
FileStr.Title= Titel;
FileStr.PathName = dn;
FileStr.Dir = Pfadname;
FileStr.File = Dateiname;
FileStr.Flags = FRQCACHINGM|FRQCACHEPURGEM;
FileStr.dirnamescolor = 8;
FileStr.devicenamescolor = 4;
strcpy(Pfadname,"Examples");
strcpy(Dateiname,"");
}
}
#ifdef GERMAN
if (!(TestFile("chems_g.dat")))
#endif
#ifdef ENGLISH
if (!(TestFile("chems_e.dat")))
#endif
{
WrConWin(conwin, NO_DATA);
Delay(100L);
Close_All(NOK);
}
PrepareSanduhr();
Load_Datafile();
sprintf(Ver, "%s V%s", ProgId, Version);
if(GfxBase->DisplayFlags & (UWORD)NTSC)
HEIGHT=200;
FirstNewScreen.Height = HEIGHT;
if (!(FirstScreen = (struct Screen *)
OpenScreen(&FirstNewScreen)))
{
WrConWin(conwin, NO_SCREEN);
Delay(150L);
Close_All(NOK);
}
LoadRGB4(&FirstScreen->ViewPort, &Pal[0], 16);
if (Metalworx(FirstScreen))
WrConWin(conwin, NO_METAL_WIN);
HauptFenster.Height = HEIGHT;
HauptFenster.Screen = FirstScreen;
if (!(Window1 = (struct Window *)
OpenWindow(&HauptFenster)))
{
WrConWin(conwin, NO_MAIN_WIN);
Delay(150L);
Close_All(NOK);
}
SetMenuStrip(Window1, &Menu1);
MyProcess = (struct Process *)FindTask((char *)0);
OldErrorWin = MyProcess->pr_WindowPtr; /* alten Window-Pointer sichern */
MyProcess->pr_WindowPtr=(APTR) Window1; /* Requests auf neuen Screen */
license();
ShowTitle(FirstScreen,ChemPrefs.Title);
PrepareLogo();
PrepareEGadgets();
}
/****************************************
* Funktion: Alles geoeffnete schliessen *
****************************************/
void Close_All(status)
BOOL status;
{
MyProcess->pr_WindowPtr=OldErrorWin; /* alten Window-Pointer wieder
herstellen */
if(reqlib_used)
PurgeFiles(&FileStr); /* Speicher f. FileListe freigeben */
FreeEGadgets();
FreeLogo();
if (RememberPtr)
FreeRemember(RememberPtr, TRUE);
if (Window1)
ClearMenuStrip(Window1);
if (Window1)
CloseWindowSafely(Window1, NULL);
if (FirstScreen)
CloseScreen(FirstScreen);
FreeSanduhr();
if (ReqBase)
CloseLibrary(ReqBase);
if (ArpBase)
CloseLibrary(ArpBase);
if (GfxBase)
CloseLibrary(GfxBase);
if (conwin != -1)
{
WrConWin(conwin, "Thanx! Have a nice day!");
Delay(100L);
close(conwin);
}
if (IntuitionBase)
CloseLibrary(IntuitionBase);
if (status == OK)
exit(0);
else
exit(1);
}